package session;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


public class SessionDataTable {
	
	//all the session data
	private List<SessionDataBlock> sessionData;
	//timeouts
	private Long tableTimeout; //how long a table will last after it is created
	private Long sessionTimeout; //how long a session should last after it is put in a table
	
	//constructor
	//NOTE: tableTimeout should be much longer than session timeout!!!
	public SessionDataTable(Long tableTimeout, Long sessionTimeout){
		sessionData = new ArrayList<SessionDataBlock>();
		this.tableTimeout = tableTimeout;
		this.sessionTimeout = sessionTimeout;
	}
	
	public void removeSession(String sessionID){
		//remove all items containing sessionID
		for(int i=sessionData.size()-1; i>=0; --i){
			sessionData.get(i).removeSession(sessionID);
		}
	}
	
	//getter
	public Long getTableTimeout(){
		return tableTimeout;
	}
	//getter
	public Long getSessionTimeout(){
		return sessionTimeout;
	}
	
	//getter
	public SessionData getSession(String sessionID, Integer version){
		//perform cleanup (this is quick, at most two comparisons because of the table/block setup)
		cleanup();
		//find most recent session object for sessionID
		for(int i=sessionData.size()-1; i>=0; --i){
			if(sessionData.get(i).getSession(sessionID)!=null){
				if(sessionData.get(i).getSession(sessionID).version==version)
					return sessionData.get(i).getSession(sessionID);
				else
					return null;
			}
		}
		return null;
	}
	
	//setter
	//NOTE: this function will automatically update the expiration of "session" 
	public ErrorCodes setSession(SessionData session){
		//change expiration
		session.expiration=System.currentTimeMillis()+sessionTimeout;
		//if the last session in the session block list expires
		//	before this session, add it there... otherwise add a
		//  new table
		if(sessionData.size()>0 && sessionData.get(sessionData.size()-1).getExpiration()>session.expiration){
			return sessionData.get(sessionData.size()-1).setSession(session);
		} else {
			//add a new table
			sessionData.add(new SessionDataBlock(System.currentTimeMillis()+tableTimeout));
			return sessionData.get(sessionData.size()-1).setSession(session);
		}
	}
	
	//perform cleanup
	private void cleanup(){
		//remove all expired tables
		while(sessionData.size()>0){
			if(sessionData.get(0).getExpiration()<System.currentTimeMillis()){
				sessionData.remove(0);
			} else {
				//if oldest table isn't expired, the rest won't be either
				break;
			}
		}
	}
}
